package com.myday.system.service.impl;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.myday.system.domain.MyTodoDateCount;
import com.myday.system.domain.vo.StatusCount;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.myday.system.mapper.MyTodoMapper;
import com.myday.system.domain.MyTodo;
import com.myday.system.service.IMyTodoService;

/**
 * 待办事项Service业务层处理
 *
 * @author xiaofengs
 * @date 2024-05-18
 */
@Service
public class MyTodoServiceImpl implements IMyTodoService {

    @Autowired
    private MyTodoMapper myTodoMapper;

    /**
     * 查询待办事项
     *
     * @param todoId 待办事项主键
     * @return 待办事项
     */
    @Override
    public MyTodo selectMyTodoByTodoId(Long todoId) {
        // 查询自己的待办事项
        MyTodo myTodo = myTodoMapper.selectMyTodoByTodoId(todoId);
        if (!myTodo.getUserId().equals(SecurityUtils.getLoginUser().getUserId())) {
            throw new RuntimeException("不能查看别人的待办事项");
        }
        return myTodoMapper.selectMyTodoByTodoId(todoId);
    }

    /**
     * 查询待办事项列表
     *
     * @param myTodo 待办事项
     * @return 待办事项
     */
    @Override
    public List<MyTodo> selectMyTodoList(MyTodo myTodo) {
        // 获取当前用户id
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        myTodo.setUserId(sysUser.getUserId());
        return myTodoMapper.selectMyTodoList(myTodo);
    }

    /**
     * 新增待办事项
     *
     * @param myTodo 待办事项
     * @return 结果
     */
    @Override
    public int insertMyTodo(MyTodo myTodo) {
        // 新增待办事项 必须只能新增自己的待办事项
        // 获取当前用户id
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        myTodo.setUserId(sysUser.getUserId());
        myTodo.setCreateTime(DateUtils.getNowDate());
        return myTodoMapper.insertMyTodo(myTodo);
    }

    /**
     * 修改待办事项
     *
     * @param myTodo 待办事项
     * @return 结果
     */
    @Override
    public int updateMyTodo(MyTodo myTodo) {
        // 修改待办事项 必须只能修改自己的待办事项
        // 获取当前用户id
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        if (!myTodo.getUserId().equals(sysUser.getUserId())) {
            throw new RuntimeException("不能修改别人的待办事项");
        }
        myTodo.setUpdateTime(DateUtils.getNowDate());
        return myTodoMapper.updateMyTodo(myTodo);
    }

    /**
     * 批量删除待办事项
     *
     * @param todoIds 需要删除的待办事项主键
     * @return 结果
     */
    @Override
    public int deleteMyTodoByTodoIds(Long[] todoIds) {
        // 删除待办事项 必须只能删除自己的待办事项
        // 获取当前用户id
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        MyTodo myTodo = new MyTodo();
        myTodo.setUserId(sysUser.getUserId());
        // 查找我的待办事项id列表
        List<Long> ts = myTodoMapper.selectMyTodoList(myTodo).stream().map(todo -> todo.getTodoId()).collect(Collectors.toList());
        if (!ts.equals(Arrays.stream(todoIds).toList())) {
            throw new RuntimeException("不能删除别人的待办事项");
        }
        return myTodoMapper.deleteMyTodoByTodoIds(todoIds);
    }

    /**
     * 删除待办事项信息
     *
     * @param todoId 待办事项主键
     * @return 结果
     */
    @Override
    public int deleteMyTodoByTodoId(Long todoId) {
        // 删除待办事项 必须只能删除自己的待办事项
        // 获取当前用户id
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        MyTodo myTodo = new MyTodo();
        myTodo.setUserId(sysUser.getUserId());
        // 查找我的待办事项id列表
        List<Long> ts = myTodoMapper.selectMyTodoList(myTodo).stream().map(todo -> todo.getTodoId()).collect(Collectors.toList());
        if (!ts.contains(todoId)) {
            throw new RuntimeException("不能删除别人的待办事项");
        }
        return myTodoMapper.deleteMyTodoByTodoId(todoId);
    }

    @Override
    public List<Long> getWeekStatistic() {
        List<Long> weekCount = new LinkedList<>();
        // 从周一到周日严格递增
        List<MyTodoDateCount> weekStatistic = myTodoMapper.getMyTodoDateCount(SecurityUtils.getUserId());
        // 取出本周内枞周一到周日的记录数，没有的为0
        LocalDate currentDate = LocalDate.now();
        LocalDate monday = currentDate.with(DayOfWeek.MONDAY);
        // 遍历本周的日期，初始化记录数为0
        for (int i = 0; i < 7; i++) {
            weekCount.add(0L);
        }
        // 本周的日期
        for (MyTodoDateCount todoCount : weekStatistic) {
            // 假设日期字段为 todoDate
            LocalDate todoDate = todoCount.getDate();
            Long count = todoCount.getCount();
            // 如果当前日期在本周范围内，更新对应日期的记录数
            if (todoDate.isAfter(monday.minusDays(1)) && todoDate.isBefore(monday.plusDays(7))) {
                int index = todoDate.getDayOfWeek().getValue() - 1;
                weekCount.set(index, count);
            }
        }
        return weekCount;
    }

    @Override
    public Map<String, Long> getStatusStatistic() {
        List<StatusCount> statusCount = myTodoMapper.countByStatus(SecurityUtils.getUserId());
        Map<String, Long> result = statusCount.stream()
                .collect(Collectors.
                        toMap((s)-> switch (s.getStatus()) {
                                case -1 -> "未开始";
                                case 0 -> "进行中";
                                case 1 -> "已完成";
                                default -> "已取消";
                        }, StatusCount::getCount));

        return result;
    }

    @Override
    public List<Long> getMonthStatistic() {
        List<Long> monthCount = new LinkedList<>();
        // 从一月到十二月严格递增
        List<MyTodoDateCount> monthStatistic = myTodoMapper.getMyTodoDateCount(SecurityUtils.getUserId());
        LocalDate currentDate = LocalDate.now();
        // 遍历本月的日期，初始化记录数为0
        LocalDate firstMonthofYear = currentDate.withDayOfMonth(1);
        for (int i = 0; i < 12; i++) {
            monthCount.add(0L);
        }
        // 本月的日期
        for (MyTodoDateCount todoCount : monthStatistic) {
            // 假设日期字段为 todoDate
            LocalDate todoDate = todoCount.getDate();
            Long count = todoCount.getCount();
            // 如果当前日期在本月范围内，更新对应日期的记录数
            if (todoDate.isAfter(firstMonthofYear.minusMonths(1)) && todoDate.isBefore(firstMonthofYear.plusMonths(1))) {
                int index = todoDate.getMonthValue() - 1;
                monthCount.set(index, count);
            }
        }
        return monthCount;
    }

    @Override
    public List<Long> getYearStatistic() {
        // 前年去年今年的统计数据
        List<Long> yearCount = new LinkedList<>();
        List<MyTodoDateCount> yearStatistic = myTodoMapper.getMyTodoDateCount(SecurityUtils.getUserId());
        LocalDate currentDate = LocalDate.now();
        // 获取前年
        yearCount.add(yearStatistic.stream().filter(s -> s.getDate().isBefore(currentDate.minusYears(2))).count());
        // 获取去年
        yearCount.add(yearStatistic.stream().filter(s -> s.getDate().isBefore(currentDate.minusYears(1))).count());
        // 获取今年
        yearCount.add(yearStatistic.stream().filter(s -> s.getDate().isBefore(currentDate.plusDays(1))).count());
        return yearCount;
    }

    @Override
    public SysUser selectUserByTodoId(Long todoId) {
        return myTodoMapper.selectUserByTodoId(todoId);
    }
}
